/**
*
* Copyright (c) 2011~2012 galaxy engine team.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*
*  Abstract:
*    
*
*  Author:
*    freecnjet (freecnjet@gmail.com)
*
*  Revision History:
*    Created on: 2012-03-04
*
*/

#ifndef _TRACE_H_
#define _TRACE_H_


#include <cstdio>
#include <cassert>
#include <cerrno>

__BEGIN_NAMESPACE

/************************************************************************/
/* malloc/free tag                                                      */
/************************************************************************/
#define MAX_MEMORY_FILE_SIZE 260
#define MAX_MTAG_STACK       16
#define MAX_TAGS             32

struct MemAllocInfo
{
	const char*	Filename;
	size_t      FileLine;
	size_t		Size;
	int         TagID;

	struct MemAllocInfo *pPre;
	struct MemAllocInfo *pNext;
};

extern CORE_API void PushMallocTag( int tag );
extern CORE_API void PopMallocTag( );
extern CORE_API void MallocInfo( const char* srcfile, const unsigned int line );
extern CORE_API size_t GetMemoryUsage( int tag );
extern CORE_API void MemoryDump();

/*****************************************************************************************
* debug marco
*****************************************************************************************/
#ifdef  NDEBUG
#define Assert(_Expression)     ((void)0)
#else
#define Assert(_Expression) assert(_Expression)
#endif

#ifdef  NDEBUG
#define Verify(a) Assert(a)
#else
#define Verify(a) (a)
#endif

#ifdef NDEBUG
inline void Trace(const char* _content, ...)  {}
#else
#define Trace printf
//extern CORE_API void Trace(const char* _content, ...);
//extern CORE_API void TraceW(const wchar_t* _content, ...);
#endif


/*****************************************************************************************
* error
*****************************************************************************************/

/**
* all error number
*/
enum {
	E_Ok                  = 0,        ///< Everything worked fine
	E_BadParameter        = 1,        ///< Bad parameter passed to the function
	E_OutOfRange          = 2,        ///< Value/Parameter out of range
	E_Overflow            = 3,        ///< Overflow occurred (typically buffer)
	E_Unsupported         = 4,        ///< Unsupported feature/function
	E_NotFound            = 5,        ///< The resource/object requested can't be found
	E_DeviceNotFound      = 6,        ///< The device requested can't be found
	E_AlreadyInUse        = 7,        ///< The resource is already in use
	E_FileNotFound        = 8,        ///< The file requested can't be found
	E_PathNotFound        = 9,        ///< The file's path requested can't be found
	E_Conflict            = 10,       ///< The resource/object you're registering is conflicting another
	E_LowLevelError       = 11,       ///< A low level error occurred (hardware or OS)
	E_Corrupted           = 12,       ///< Data feeding has been corrupted
	E_Processing          = 13,       ///< The operation requested is currently processing
	E_AlreadyExist        = 14,       ///< The file already exists
	E_AccessDenied        = 15,       ///< Access to the resource is denied
	E_DeviceFull          = 16,       ///< The device is full, no more appending is possible
	E_DeviceNotReady      = 17,       ///< The device is not ready for r/w operations
	E_NotInitialized      = 18,       ///< The device is not ready for r/w operations
	E_AlreadyInitialized  = 19,       ///< The device is already initialized
	E_NoDataAvailable     = 20,       ///< No data can be obtained from the device
	E_WrongVersion        = 21,       ///< The file/data read has a wrong version number
	E_OutOfMemory         = 22,       ///< Not enough memory to complete the operation
	E_TimeOut             = 23,       ///< Operation timed out
	E_InputError          = 24,       ///< Input error occurred (typically read operation that failed)
	E_OutputError         = 25,       ///< Output error occurred (typically write operation that failed)
	E_OutOfMBufs          = 26,       ///< The device/or communication object ran out of internal MBufs
	E_OutOfRequests       = 27,       ///< The communication object ran out of request placeholder
	E_OperationAborted    = 28,       ///< Operation has aborted (often use in asynch module)
	E_SharingViolation    = 29,       ///< Shared resource error (mainly file sharing)
	E_BufferTooSmall      = 30,       ///< Provided buffer is too small to complete operation
	E_Unknown             = 31,       ///< Unknown error
	E_Err_Max
};

extern CORE_API const char* GetErrDescription( int err );
extern CORE_API void SetError( int err );
extern CORE_API int GetError( );

typedef void (*ErrorCallback)(int e);
void SetErrorCallback();

class ErrorKeepGuard {
public:
	ErrorKeepGuard() {
		m_error = GetError();
	}
	~ErrorKeepGuard() {
		SetError(m_error);
	}

private:
	int m_error;
};


/*****************************************************************************************
* time statistic
*****************************************************************************************/


__END_NAMESPACE


#endif //~~
